iT邦幫忙

2021 iThome 鐵人賽

DAY 6
0

中秋節快樂!!! 這幾天烤肉烤到有點忘記打Code的感覺了,那提到忘記這個詞,我們就想到我們平常密碼也有可能會忘記,那怎麼辦呢!? Firebase Auth提供我們透過寄到我們註冊的email帳戶,讓我們更改密碼!

頁面長相會是這樣,簡單明瞭又不失小小偷懶

https://ithelp.ithome.com.tw/upload/images/20210921/20138017Xqy0Ik9UXV.png

零、建立ForgotAccountFragment

這個部分就是要記得設定databinding,以及繼承BaseFragment

一.Layout

1.設定string

由於這次我們要做的layout,有幾個尺寸是非常客製化,很難達到複用,所以我有許多layout的尺寸都是寫死的。如果覺得有必要的話,可以自己斟酌是否要寫入dimen

string 如下

<string name="toolbar_title_forgot_account">忘記密碼</string>
<string name="forgotAccount_find_your_account">找回密碼</string>
<string name="forgotAccount_description">請輸入您的信箱,我們將會傳送信箱到您的郵件地址。並請您透過信箱去完成更改密碼的手續。 </string>
<string name="submit">送出</string>
<string name="forgotAccount_already_send_email">我們已經寄送更改密碼的信件到您信箱囉!</string>

2.這次layout比較簡單,一樣直接貼Code

<?xml version="1.0" encoding="utf-8"?>

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".ui.fragment.ForgotAccountFragment">

        <FrameLayout
            android:id="@+id/fl_forgot_fragment"
            android:layout_width="match_parent"
            android:layout_height="@dimen/login_banner_height"
            android:background="@color/light_pewter_blue"
            app:layout_constraintTop_toTopOf="parent">

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar_forgot_fragment"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:layout_gravity="top">


                <com.example.petsmatchingapp.utils.JFTextView
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:text="@string/toolbar_title_forgot_account"
                    android:gravity="center"
                    android:textColor="@color/white"
                    android:textSize="@dimen/toolbar_textSize"/>


            </androidx.appcompat.widget.Toolbar>

        </FrameLayout>

        <com.example.petsmatchingapp.utils.JFTextView
            android:id="@+id/tv_forgot_fragment_forgot_password"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toBottomOf="@id/fl_forgot_fragment"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            android:text="@string/forgotAccount_find_your_account"
            android:layout_marginTop="35dp"
            android:textSize="20sp" />

        <com.example.petsmatchingapp.utils.JFTextView
            android:id="@+id/tv_forgot_fragment_description"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toBottomOf="@id/tv_forgot_fragment_forgot_password"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            android:text="@string/forgotAccount_description"
            android:layout_marginTop="10dp"
            android:layout_marginStart="50dp"
            android:layout_marginEnd="50dp"
            android:textSize="18sp" />

        <com.google.android.material.textfield.TextInputLayout
            android:id="@+id/tip_forgot_enter_email"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toBottomOf="@id/tv_forgot_fragment_description"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
            android:layout_marginTop="@dimen/tip_margin_top_bottom"
            android:layout_marginStart="@dimen/tip_margin_start_end"
            android:layout_marginEnd="@dimen/tip_margin_start_end">

            <com.example.petsmatchingapp.utils.JFEditText
                android:id="@+id/ed_forgot_email"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="@string/hint_enter_your_email"
                android:padding="@dimen/edText_padding"
                android:textSize="@dimen/edText_textSize">

            </com.example.petsmatchingapp.utils.JFEditText>



        </com.google.android.material.textfield.TextInputLayout>


        <com.example.petsmatchingapp.utils.JFButton
            android:id="@+id/btn_forgot_submit"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toBottomOf="@id/tip_forgot_enter_email"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            android:layout_marginStart="16dp"
            android:layout_marginEnd="16dp"
            android:layout_marginTop="30dp"
            android:foreground="?attr/selectableItemBackground"
            android:background="@drawable/button_background"
            android:textColor="@color/white"
            android:text="@string/submit"/>

    </androidx.constraintlayout.widget.ConstraintLayout>

</layout>

二、回到Code

1.確認使用者是否輸入為空

private fun validDataForm(): Boolean{
        
       return when{
           TextUtils.isEmpty(binding.edForgotEmail.text.toString().trim()) -> {
               showSnackBar(resources.getString(R.string.hint_enter_your_email),true)
               false
           }
           else -> true
       }
    }

2.我們要呼叫 AccountViewModel,所以我們一樣要寫下

private val accountViewModel: AccountViewModel by sharedViewModel()

3.建立button的onClick事件

由於我們這次這個Fragment沒有特別多的onClick需要我們去設定,所以就直接用以下方法,這樣就不用在Fragment後面要去設定繼承

binding.btnForgotSubmit.setOnClickListener{
						//確認email欄位是否為空
            if (validDataForm()){
                showDialog(resources.getString(R.string.please_wait))
								//拿到user輸入的edText資料
                val email = binding.edForgotEmail.text.toString().trim()
                accountViewModel.sendEmailToResetPassword(this,email)
            }
        }

★這時候會發現我們的 sendEmailToResetPassword 這邊是紅的,但沒關係,我們等等來做!

4.新增AccountViewModel設定忘記密碼寄信的funtion

我們的所有的與Firebase溝通的,都會透過viewModel。

fun sendEmailToResetPassword(fragment: ForgotAccountFragment,email: String){

				//直接拿到Auth的 Instance,就可以叫出 sendPasswordResetEmail了!
                FirebaseAuth.getInstance().sendPasswordResetEmail(email)
                    .addOnSuccessListener {
                    fragment.sendEmailSuccessful()
                    }
                    .addOnFailureListener {
                    fragment.sendEmailFail(it.toString())
                    }

        }

5.新增sendPassword的成功跟失敗後所要回饋的funtion

非常鼓勵有看過昨天/前天文章的夥伴們,可以自己嘗試做,或是設定不同的funtion,這樣會比較有趣,也比較會有印象!

fun sendEmailSuccessful(){
        hideDialog()
        showSnackBar(resources.getString(R.string.forgotAccount_already_send_email),false)
    }

    fun sendEmailFail(e: String){
        hideDialog()
        showSnackBar(e,true)
    }

6.ForgotAccountFragment的Toolbar新增返回鍵

binding.toolbarForgotFragment.setNavigationIcon(R.drawable.ic_baseline_arrow_back_24)
binding.toolbarForgotFragment.setNavigationOnClickListener { 
            requireActivity().onBackPressed()
        }

Navigation設定

1.到 account_nav,新增今天做好的 ForgotAccountFragment,並且把 LoginFragment連到ForgotAccountFragment

2.LoginFragment,在onClick的funtion新增

binding.tvForgotPassword -> {
                nav.navigate(R.id.action_loginFragment_to_forgotAccountFragment)
            }

★別忘了在onCreateView也要新增

binding.tvForgotPassword.setOnClickListener(this)

就好囉,你可以去當初註冊的email帳號,去察看信件,就可以Reset你的密碼啦!!


上一篇
【Day5】註冊畫面 X Firestore Database
下一篇
【Day7】BottomNavigation X ProfileFragment
系列文
30天建立寵物約散App-Android新手篇30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言